package no.jschief.lupercal.poc.waypointing;

import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.material.RenderState.FaceCullMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.scene.debug.Arrow;
import com.jme3.scene.shape.Line;
import com.jme3.scene.shape.Sphere;
import com.jme3.util.BufferUtils;

public class GeoFactory {
			
	public static Spatial createDebugOrigin(AssetManager am) {
		Material redMat = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
		Material greenMat = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
		Material blueMat = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
		
		redMat.setColor("Color", ColorRGBA.Red);
		greenMat.setColor("Color", ColorRGBA.Green);
		blueMat.setColor("Color", ColorRGBA.Blue);
		
		Arrow originX = new Arrow(Vector3f.ZERO);
		Arrow originY = new Arrow(Vector3f.ZERO);
		Arrow originZ = new Arrow(Vector3f.ZERO);
		Geometry originXgeo = new Geometry("DebugArrowOriginX", originX);
		Geometry originYgeo = new Geometry("DebugArrowOriginY", originY);
		Geometry originZgeo = new Geometry("DebugArrowOriginZ", originZ);
		originXgeo.setMaterial(redMat);
		originYgeo.setMaterial(blueMat);
		originZgeo.setMaterial(greenMat);
		originX.setLineWidth(3);
		originY.setLineWidth(1);
		originZ.setLineWidth(3);
		originX.setArrowExtent(Vector3f.UNIT_X);
		originY.setArrowExtent(Vector3f.UNIT_Y);
		originZ.setArrowExtent(Vector3f.UNIT_Z);
		originXgeo.setLocalScale(40);
		originYgeo.setLocalScale(30);
		originZgeo.setLocalScale(40);
		
		Node node = new Node();
		node.attachChild(originXgeo);
		node.attachChild(originYgeo);
		node.attachChild(originZgeo);
		
		return node;
	}
	
	public static Geometry createDebugMark(AssetManager am, ColorRGBA color) {
		Sphere sphere = new Sphere(6, 6, 0.06f);
		Geometry debugMark = new Geometry("DebugMark", sphere);
		Material material = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
		material.setColor("Color", color);
		debugMark.setMaterial(material);
		
		return debugMark;
	}
	
	public static Geometry createDebugArrow(AssetManager am, ColorRGBA color, Vector3f direction) {
		Arrow arrow = new Arrow( direction );
		Geometry arrowGeo = new Geometry("DebugArrow", arrow);

		Material material = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
		material.setColor("Color", color);
		arrowGeo.setMaterial( material );
		
		return arrowGeo;
	}
	
	public static Geometry createDebugLine(AssetManager am, ColorRGBA color, Vector3f start, Vector3f end) {
		Line line = new Line( start, end );
		Geometry lineGeo = new Geometry("DebugLine", line);

		Material material = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
		material.setColor("Color", color);
		lineGeo.setMaterial( material );
		
		return lineGeo;
	}

	public static void addWireframe( Geometry geo, AssetManager am ) {
        Mesh wireframe = geo.getMesh().clone();
        Geometry wireframeGeo = new Geometry(geo.getName() + "Wire", wireframe);
        Material wireframeMat = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
        wireframeMat.setColor("Color", ColorRGBA.White);
        wireframeMat.getAdditionalRenderState().setWireframe(true);
        wireframeGeo.setMaterial(wireframeMat);
        wireframeGeo.setLocalTranslation( geo.getLocalTranslation() );
        wireframeGeo.setLocalRotation( geo.getLocalRotation() );
        geo.getParent().attachChild( wireframeGeo );
	}
	
	public static Geometry createPlate(AssetManager am, ColorRGBA color, Vector3f downLeft, Vector3f downRight, Vector3f upLeft, Vector3f upRight) {
		Mesh m = new Mesh();

		
		// First segment, lets build the starting wall (cross section)
        // Vertex positions in space
        Vector3f [] vertices = new Vector3f[4];

        vertices[0] = downLeft;
        vertices[1] = downRight;			
        vertices[2] = upLeft;
        vertices[3] = upRight;

//        System.out.println("0 " + vertices[0]);
//        System.out.println("1 " + vertices[1]);
//        System.out.println("2 " + vertices[2]);
//        System.out.println("3 " + vertices[3]);
            
        // Texture coordinates
        Vector2f [] texCoord = new Vector2f[4];
        texCoord[0] = new Vector2f(0,0);
        texCoord[1] = new Vector2f(1,0);
        texCoord[2] = new Vector2f(0,1);
        texCoord[3] = new Vector2f(1,1);
        
        // Indexes. We define the order in which mesh should be constructed
//        int [] indexes = {2,3,0 };
        int [] indexes = {2,0,1 , 1,3,2};

        // Setting buffers
        m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
        m.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
        m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes));
        m.updateBound();
        
        // Creating a geometry, and apply a single color material to it
        Geometry geo = new Geometry("PlateMesh", m);
              
        
        Material mat = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", color);
        mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
        mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
        
        geo.setMaterial(mat);
        geo.setQueueBucket( Bucket.Translucent );

        return geo;
	}

}
